/* 

==========================================================

DX490a - Summer 2010

Instructor: Stelios Manousakis

==========================================================

Class 16.1:

Networking 2: Communication within a Local-Area-Network (LAN): SUPPLEMENT

Contents:

• A simple example (remote computer)

• An example with sound (remote computer)

==========================================================

*/



// ================= REMOTE MACHINE SUPPLEMENT =================

// This file is for use within the remote computer


// ====== A SIMPLE EXAMPLE: REMOTE COMPUTER ======


// In this simple example, we will create a GUI interface with two knobs, one to send data to a remote machine, and one to receive.


// 1. connecting:

~remoteComp = NetAddr("stm.local", 57120); // replace the IP ("Tesla.local") with the IP or name of the machine you want to connect to


// 2. making a responder for receiving

r = OSCresponder(~remoteComp, 'dxlab8', { arg time, resp, msg; 

[time, msg[1]].postln;

{~recKnob.value_(msg[1])}.defer;

}).add;



// 3. Making a GUI window with a knob to send, and a knob to receive:

(

var window = Window.new("Networking test",Rect(318, 456, 400, 400)).front;

~recKnob = Knob.new(window,Rect(175, 205, 217, 189))

.action_{|v| };

~sendKnob = Knob.new(window,Rect(8, 11, 216, 188))

.action_{|v| 

~remoteComp.sendMsg('stmIncoming', v.value); // << action: sending to remote machine

};

StaticText.new(window,Rect(24, 333, 148, 50))

.string_("Receive some data -->>")

.action_{|v| };

StaticText.new(window,Rect(229, 15, 130, 47))

.string_("<<-- Send some data")

.action_{|v| };

)


/* Now, do the same in the remote machine, replacing in:

1. the IP of the receiving machine to the IP of this one

2. the cmdName of the OSCresponder to the name you're using in (3)

3. Replace the name you're using in (3) with the name you use in (2)

*/


// Don't forget to remove your responder once you're done!

r.remove




// ====== AN EXAMPLE WITH SOUND: REMOTE ======

// In this simple example, we will create the same GUI interface with two knobs, except this time the 'sending' knob will get data from analysis of the sound in the local machine, and will send the data to the remote machine to affect the synthesis there - and vice versa.


// • Synthesis: a self-phase-modulated Sinewave, with analysis to show how noisy it is:


s.boot;


(

~mult = 4;

// buffer for FFT 

~buf = Buffer.alloc(s,2048,1); 

// the synthdef

~fdbFM = CtkSynthDef(\fdbSine, {arg freq, fdbAmt, amp, pollFreq = 2, gate = 1;

var sine, mod, fdbIn, fdbOut, env, chain, flatness;

fdbIn = LocalIn.ar(1);

env = EnvGen.kr(Env.new([0.00001, 1, 1, 0.00001], [0.05, 0.9, 0.5], [\exp, \sin], 1), gate,  doneAction: 2);

mod = fdbIn * fdbAmt;

sine = SinOsc.ar(freq, mod, amp); // fdb phase modulation

chain = FFT(~buf, sine);

flatness = SpecFlatness.kr(chain);

SendReply.kr(Impulse.kr(pollFreq), 'flatness', flatness);

Out.ar(0, sine * env);

fdbOut = LocalOut.ar(sine);

})

);


// 1. connecting:

~remoteComp = NetAddr("stm.local", 57120); // replace the IP ("Tesla.local") with the IP or name of the machine you want to connect to


// 2. making a responder for receiving

r = OSCresponder(~remoteComp, 'dxlab8', { arg time, resp, msg; 

[time, msg[1]].postln;

{~recKnob.value_(msg[1])}.defer;

~note.fdbAmt_(msg[1] * ~mult + 1)

}).add;



// 2a. making a responder for receiving from the analysis data from the synthdef, and moving the knob

~noisiness = OSCresponder(n, 'flatness', { arg time, resp, msg; 

msg[3].postln;

{~sendKnob.valueAction_(msg[3])}.defer; // naturally, it would be more efficient to send the message directly to the remote server, this is just for demonstration purposes...

}).add;



// 3. Making a GUI window with a knob to send, and a knob to receive:

(

var window = Window.new("Networking test",Rect(318, 456, 400, 400)).front;

~recKnob = Knob.new(window,Rect(175, 205, 217, 189))

.action_{|v| };

~sendKnob = Knob.new(window,Rect(8, 11, 216, 188))

.action_{|v| 

~remoteComp.sendMsg('stmIncoming', v.value); // << action: sending to remote machine

};

StaticText.new(window,Rect(24, 333, 148, 50))

.string_("Receive some data -->>");

StaticText.new(window,Rect(229, 15, 130, 47))

.string_("<<-- Send some data");

)




~note = ~fdbFM.new().freq_(160).fdbAmt_(3.5).amp_(0.5).play

// change some numbers

~note.freq_(124)

~note.fdbAmt_(5.4)

~note.fdbAmt_(1244)

~mult = 4.6

~note.pollFreq_(2.6)

~note.release


// remove the responders

r.remove;

~noisiness.remove;